Package de.yaams.maker.programm.plugins

Source Code of de.yaams.maker.programm.plugins.PluginLoader

/**
*
*/
package de.yaams.maker.programm.plugins;

import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.Arrays;
import java.util.HashMap;

import org.apache.commons.lang.Validate;
import org.apache.log4j.Level;
import org.ini4j.Wini;

import de.yaams.maker.helper.FileHelper;
import de.yaams.maker.helper.Log;
import de.yaams.maker.helper.NetHelper;
import de.yaams.maker.helper.Setting;
import de.yaams.maker.helper.SystemHelper;
import de.yaams.maker.helper.extensions.ExtentionManagement;
import de.yaams.maker.helper.extensions.IExtension;
import de.yaams.maker.helper.gui.YDialog;
import de.yaams.maker.helper.gui.YEx;
import de.yaams.maker.helper.gui.YMessagesDialog;
import de.yaams.maker.helper.gui.form.FormInfo;
import de.yaams.maker.helper.gui.form.core.FormBuilder;
import de.yaams.maker.helper.language.I18N;
import de.yaams.maker.programm.YAamsCore;
import de.yaams.maker.programm.plugins.PluginInfo.STAGE;

/**
* @author abby
*
*/
public class PluginLoader {

  public static File folder;
  protected static HashMap<String, PluginInfo> plugins;
  private static boolean searchOnline;

  // Parameters
  @SuppressWarnings("rawtypes")
  private static final Class[] parameters = new Class[] { URL.class };

  /**
   *
   */
  public static void init(YMessagesDialog ymd) {
    // save settings
    ExtentionManagement.add(ExtentionManagement.SAVE, new IExtension() {

      @Override
      public void work(HashMap<String, Object> objects) {
        FileHelper.saveXML(new File(folder, "setting.xml"), plugins);

      }
    });

    // has folder?
    if (folder == null) {
      folder = new File(YAamsCore.programPath, "Plugins");
    }

    // check folder
    if (!FileHelper.checkPath(folder, ymd, true, true)) {
      return;
    }

    // load active settings
    plugins = (HashMap<String, PluginInfo>) FileHelper.loadXML(new File(folder, "setting.xml"));
    if (plugins == null) {
      plugins = new HashMap<String, PluginInfo>();
    }

    installOnlineInfo(false);

    // extract plugins?
    for (File path : folder.listFiles(new FileFilter() {

      @Override
      public boolean accept(File f) {
        return f.getName().toLowerCase().endsWith(".yex");
      }
    })) {
      try {
        // get id
        String id = PluginLoader.getIDForFile(path);

        // create folder
        FileHelper.mkdirs(new File(folder, id));

        // extract file
        FileHelper.extractArchive(path, new File(folder, id));

        // delete archiv
        FileHelper.deleteFile(path);

        // show message
        // md.add(I18N.t("Entpacken vom Plugin {0} war erfolgreich.",
        // id),
        // Level.INFO_INT);
        Log.ger.info("Extract " + path);
        // mess.add(I18N.t("Extract {0} successful.", id));
      } catch (final Throwable t) {
        ymd.add(YEx.toString("Can not add Plugin " + path, t, false), Level.WARN_INT);
      }
    }

    HashMap<String, PluginInfo> order = new HashMap<String, PluginInfo>();

    // load all plugins from the folder
    for (File path : folder.listFiles(new FileFilter() {

      @Override
      public boolean accept(File f) {
        return f.isDirectory();
      }
    })) {
      // exist?
      if (!plugins.containsKey(path.getName())) {
        plugins.put(path.getName(), new PluginInfo(path));
      }
    }

    // add all existing plugins
    for (String key : plugins.keySet()) {
      order.put(key, plugins.get(key));
    }

    // start all plugins
    // load plugins
    while (true) {
      boolean chance = false;
      for (String id : order.keySet().toArray(new String[order.keySet().size()])) {
        // can start?
        STAGE erg = order.get(id).canUse(ymd, order.keySet().toArray(new String[order.keySet().size()]));

        // add it?
        if (erg == STAGE.USEABLE || erg == STAGE.NOTUSEABLE) {
          order.remove(id);
          chance = true;
        }
      }
      if (chance == false) {
        break;
      }
    }

    // are modules missing?
    for (String id : order.keySet()) {
      ymd.add(I18N.t("Kann Plugin {0} nicht starten.", order.get(id).getTitle()), Level.INFO_INT);
    }

  }

  /**
   * Helpermethod
   *
   * @param base
   */
  public static void addSearchFolder(File base) {
    // add it
    addFolder(base);

    // search für jars inside and it itf
    for (File f : Arrays.asList(base.listFiles(new FileFilter() {

      @Override
      public boolean accept(File f) {
        return f.getName().endsWith(".jar") || f.isDirectory();
      }
    }))) {
      // add it
      if (f.isDirectory()) {
        addSearchFolder(f);
      } else {
        addFolder(f);
      }
    }
  }

  /**
   * Add the .jar folder to the class loader
   *
   * @param u
   * @throws IOException
   */
  @SuppressWarnings({ "rawtypes", "unchecked" })
  protected static void addFolder(final File p) {
    Log.ger.info("Add to search path: " + p);
    try {
      final URL u = p.toURI().toURL();

      final URLClassLoader sysLoader = (URLClassLoader) ClassLoader.getSystemClassLoader();
      final URL urls[] = sysLoader.getURLs();
      for (URL url : urls) {
        if (url.toString().equalsIgnoreCase(u.toString())) {
          return;
        }
      }
      final Class sysclass = URLClassLoader.class;
      try {
        final Method method = sysclass.getDeclaredMethod("addURL", parameters);
        AccessController.doPrivileged(new PrivilegedAction<Object>() {
          @Override
          public Object run() {
            method.setAccessible(true);
            return "";
          }
        });

        method.invoke(sysLoader, new Object[] { u });
      } catch (final Throwable t) {
        throw new IOException("Error, could not add URL to system classloader", t);
      }
    } catch (final Throwable t) {
      YEx.info("Can not add " + p + " to plugin search path", t);
    }
  }

  /**
   * @return the plugins
   */
  public static HashMap<String, PluginInfo> getPlugins() {
    return plugins;
  }

  /**
   * Is this plugin install?
   *
   * @param id
   * @return
   */
  public static boolean isInstall(String id) {
    return plugins.containsKey(id) && plugins.get(id).isUseable();
  }

  /**
   * Get this plugin
   *
   * @return
   */
  public static PluginInfo get(String key) {
    return plugins.get(key);
  }

  /**
   * Helpermethod to uninstall a plugin
   *
   * @param key
   */
  public static void uninstall(String key) {
    // ask user
    if (!YDialog.delete(get(key).getTitle(), "plugin")) {
      return;
    }

    // uninstall it
    FileHelper.deleteTree(new File(folder, key));
    plugins.remove(plugins.get(key));

  }

  /**
   * Look online for the catalog and load it
   *
   * @param background
   */
  public static void installOnlineInfo(boolean manuell) {
    // check settings
    if (!Setting.get("net.access", true) && !manuell) {
      return;
    }

    File catalog = new File(folder, "catalog.ini");

    // update catalog?
    if (manuell || Setting.get(PluginPlugin.CHECK, 168) != -1
        && System.currentTimeMillis() - Setting.get("plugins.updateCheck", 0L) >= Setting.get(PluginPlugin.CHECK, 168L) * 3600000) {
      Setting.set("plugins.updateCheck", System.currentTimeMillis());
      Log.ger.info("Check updates");

      // has internet?
      if (!NetHelper.hasInternet(manuell)) {
        return;
      }

      // delete file
      if (catalog.exists()) {
        FileHelper.deleteFile(catalog);
      }

      // has internet?
      String link = NetHelper.getContentAsString("http://www.yaams.de/plugin/?action=catalog");

      // dl file?
      if (!NetHelper.downloadFile(catalog, link)) {
        return;
      }
    } else {
      // no update check?
      if (!catalog.exists()) {
        Log.ger.info("No update check");
        return;
      }
    }

    // exist?
    if (!FileHelper.checkPath(I18N.t("Kann Pluginkatalog nicht öffnen"), catalog, false, false)) {
      return;
    }

    try {
      FormBuilder f = new FormBuilder("plugin.updates");

      // run over all plugins
      final Wini ini = new Wini(catalog);
      // add all
      for (final String id : ini.keySet()) {
        // create folder?
        File o = new File(new File(folder, id), "online.ini");
        if (!o.getParentFile().exists()) {
          FileHelper.mkdirs(o.getParentFile());
        }

        // clear file
        if (o.exists()) {
          o.delete();
        }
        o.createNewFile();

        // save in folder
        Wini out = new Wini(o);
        out.add(id, ini.get(id));
        out.store();

        // exist?
        if (!PluginLoader.getPlugins().containsKey(id)) {
          PluginLoader.getPlugins().put(id, new PluginInfo(o.getParentFile()));
        }

        // load online
        get(id).checkOnline(ini.get(id), f);
      }

      // found it?
      if (f.getHeader("basic").getElements().size() > 0) {
        f.addElement("basic.desc", new FormInfo("", I18N.t("Wähle die Plugins aus, die geupdatet werden sollen.")).setSorting(-1));
        YDialog.showForm(I18N.t("Es sind Updates verfügbar"), "plugin_web", f);
        SystemHelper.restart();
      }

    } catch (Throwable t) {
      YEx.info("Can not read catalog " + catalog, t);
    }

    searchOnline = true;
  }

  /**
   * Method to download a plugin
   *
   * @param key
   */
  public static boolean installFromOnline(String id) {
    // has online info?
    if (!searchOnline) {
      installOnlineInfo(true);
    }

    try {
      Validate.notNull(get(id));
    } catch (Exception e) {
      YEx.warn("Plugin " + id + " not exist.", e);
      return false;
    }
    // dl
    NetHelper.downloadFile(new File(PluginLoader.folder, id + ".yex"), get(id).getOnlineElement("download", "No Link"));

    return true;
  }

  /**
   * Create from a filename the id
   *
   * @param name
   * @return
   */
  public static String getIDForFile(File name) {
    String end = name.getName().toLowerCase();

    // run over the name and find the positon
    for (int i = 0, l = end.length(); i < l; i++) {
      if (!Character.isLetter(end.charAt(i))) {
        end = end.substring(0, i);
        break;
      }
    }

    return end;
  }
}
TOP

Related Classes of de.yaams.maker.programm.plugins.PluginLoader

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.